package han.cirno.corrupt.modules.library

import androidx.activity.compose.LocalActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import han.cirno.corrupt.compose.localeStringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import androidx.core.graphics.createBitmap
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.palette.graphics.Palette
import han.cirno.corrupt.R
import han.cirno.corrupt.activity.main.LocalNavController
import han.cirno.corrupt.activity.main.NavItem
import han.cirno.corrupt.activity.main.navigate
import han.cirno.corrupt.components.school.impl.fafu.FafuLibClient
import han.cirno.corrupt.compose.TextWithIcon
import han.cirno.corrupt.compose.VerticalSpacer

@Composable
fun LibraryLayout() = Box(modifier = Modifier.fillMaxSize()){
    val libraryViewModel: LibraryViewModel = hiltViewModel(LocalActivity.current as AppCompatActivity)
    var searchText by libraryViewModel.keyword
    val searchStatus by  libraryViewModel.searchStatus
    val firstLoading by libraryViewModel.isFirstLoading
    val contentLoading by libraryViewModel.isContentLoading
    Column(modifier = Modifier
        .fillMaxSize()
        .padding(horizontal = 16.dp)
        .verticalScroll(rememberScrollState())) {
        OutlinedTextField(
            enabled = !firstLoading,
            leadingIcon = {
                Icon(
                    painter = painterResource(R.drawable.baseline_search_24),
                    contentDescription = null) },
            modifier = Modifier.fillMaxWidth(),
            value = searchText,
            singleLine = true,
            onValueChange = {searchText=it},
            keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
            keyboardActions = KeyboardActions(onSearch = {
                libraryViewModel.performSearch()
            })
        )
        Column(modifier = Modifier.weight(1f)) {
            AnimatedContent(searchStatus) {p->
                when(p){
                    0-> IdleScreen()
                    1-> {}
                    2-> ResultScreen()
                    3-> NoResultScreen()
                }
            }
        }
    }
    AnimatedVisibility(visible = firstLoading||contentLoading,enter=fadeIn(),exit=fadeOut()) { LoadingScreen() }
    Palette.from(createBitmap(1,1)).generate {  }
}

@Composable
fun LibraryContentLayout()= Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){
    val libraryViewModel: LibraryViewModel = hiltViewModel(LocalActivity.current as AppCompatActivity)
    val result = libraryViewModel.contentScreenBook.value
    val detail = libraryViewModel.contentScreenContent.value
    if (result==null||detail==null)return
    BookInfo(result)
    Column(modifier = Modifier.padding(horizontal = 16.dp)) {
        TextWithIcon(
            modifier = Modifier.fillMaxWidth(),
            iconRes = R.drawable.baseline_description_24,
            text = detail.description
        )
        TextWithIcon(
            modifier = Modifier.fillMaxWidth(),
            iconRes = R.drawable.baseline_qr_code_24,
            text = detail.isbnAndPrice
        )
        TextWithIcon(
            modifier = Modifier.fillMaxWidth(),
            iconRes = R.drawable.baseline_text_format_24,
            text = detail.payload
        )
        TextWithIcon(
            modifier = Modifier.fillMaxWidth(),
            iconRes = R.drawable.baseline_category_24,
            text = detail.theme
        )
    }
    VerticalSpacer(4.dp)
    detail.bookPlaces.forEach {
        Card(
            modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
            elevation = CardDefaults.cardElevation(2.dp)) {
            BookBorrowInfo(it)
        }
    }
}

@Composable
fun NoResultScreen()= Column(
    modifier = Modifier.fillMaxSize(),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally){
    Icon(
        modifier = Modifier.size(128.dp),
        painter = painterResource(R.drawable.baseline_search_off_24),
        contentDescription = null)
    Text(text= localeStringResource(R.string.library_search_notFound_hint))
}

@Composable
fun ResultScreen() = Column(
    modifier = Modifier.fillMaxSize(),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally){
    val libraryViewModel: LibraryViewModel = hiltViewModel(LocalActivity.current as AppCompatActivity)
    val listState = rememberLazyListState()
    val shouldLoadMore = remember {
        derivedStateOf {
            val layoutInfo = listState.layoutInfo
            val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
            lastVisibleItem?.index != null &&
                    lastVisibleItem.index >= libraryViewModel.resultsList.size-1 &&
                    !libraryViewModel.isAppendLoading.value
        }
    }
    LaunchedEffect(shouldLoadMore.value) {
        if(shouldLoadMore.value)
            libraryViewModel.loadMore()
    }
    LazyColumn(modifier = Modifier.fillMaxSize(), state = listState) {
        items(libraryViewModel.resultsList,key={it.hashCode()}) {
            BookCard(it)
        }
        if(libraryViewModel.nowPage.intValue<=libraryViewModel.totalPage.intValue)
            item {
                Box(modifier = Modifier.fillMaxWidth().height(48.dp), contentAlignment = Alignment.Center) {
                    CircularProgressIndicator(
                        modifier = Modifier.size(32.dp).padding(vertical = 4.dp))
                }
            }
    }
}

@Composable
fun BookCard(result: FafuLibClient.SearchResult){
    val libraryViewModel: LibraryViewModel = hiltViewModel(LocalActivity.current as AppCompatActivity)
    val navController= LocalNavController.current
    Card(
        modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
        elevation = CardDefaults.cardElevation(2.dp),
        onClick = {
            libraryViewModel.loadDetail(result){
                navController.navigate(NavItem.LibraryDetailFunction)
            }
        }){
        BookInfo(result)
    }
}

@Composable
fun BookInfo(result: FafuLibClient.SearchResult){
    Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
        Text(
            text=result.name,
            style = MaterialTheme.typography.titleLarge)
        VerticalSpacer(4.dp)
        Row(modifier = Modifier.fillMaxWidth()) {
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = R.drawable.baseline_account_circle_24,
                text = result.author
            )
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = R.drawable.baseline_code_24,
                text = result.callNumber
            )
        }
        Row(modifier = Modifier.fillMaxWidth()) {
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = R.drawable.baseline_translate_24,
                text = result.type
            )
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = R.drawable.baseline_collections_bookmark_24,
                text = result.press
            )
        }
    }
}

@Composable
fun BookBorrowInfo(place: FafuLibClient.BookPlace){
    Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
        Row(modifier = Modifier.fillMaxWidth()) {
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = R.drawable.baseline_place_24,
                text = place.place
            )
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = R.drawable.baseline_numbers_24,
                text = place.serial
            )
        }
        Row(modifier = Modifier.fillMaxWidth()) {
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = R.drawable.baseline_code_24,
                text = place.code
            )
            TextWithIcon(
                modifier = Modifier.weight(1f),
                iconRes = when{
                    place.status.contains("非可借")||place.status.contains("借出")->
                        R.drawable.baseline_clear_24_red
                    place.status.contains("可借")->
                        R.drawable.baseline_check_24_green
                    else->R.drawable.baseline_question_mark_24
                },
                text = when{
                    place.status.contains("非可借")->
                        localeStringResource(R.string.library_info_status_notBorrowable)
                    place.status.contains("可借")->
                        localeStringResource(R.string.library_info_status_borrowable)
                    else->place.status
                }
            )
        }
    }
}

@Composable
fun LoadingScreen()= Column(
    modifier = Modifier.fillMaxSize().clickable {  }.background(Color.Black.copy(alpha=0.3f)),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally){
    LinearProgressIndicator()
    VerticalSpacer(4.dp)
    Text(text= localeStringResource(R.string.library_search_loading))
}

@Composable
fun IdleScreen()= Column(
    modifier = Modifier.fillMaxSize(),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally){
    Icon(
        modifier = Modifier.size(128.dp),
        painter = painterResource(R.drawable.baseline_search_24),
        contentDescription = null)
    Text(text= localeStringResource(R.string.library_search_hint))
}